package gui;

import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.InetAddress;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.border.Border;
import javax.swing.border.EtchedBorder;
import javax.swing.border.TitledBorder;

import parameters.DefaultParameterValues;
import parameters.RlmServerParameters;
import upnp.UPnpManager;
import utils.NICInfo;
import utils.NICManager;
import utils.NetworkUtils;
import utils.PortScanner;

public class SettingsDialog extends JDialog {
	
	/**
	 * Parent - prozor aplikacije.
	 */
	private GUIWindow owner;
	
	
	private JPanel jContentPane = null;
	
	
	private JPanel serverPanel = null;
	private JPanel databasePanel = null;
	private JPanel buttonPanel = null;
	private JPanel nicPanel = null;

	private GridBagLayout serverGridBag = null;
	private GridBagLayout dbGridBag = null;
	private FlowLayout buttonFlow = null;
	private GridBagLayout nicPanelGridBag = null;
	
	
	private JButton okButton = null;
	private JButton cancelButton = null;
	
	
	private JLabel serverNameLabel = null;
	private JTextField serverNameField = null;
	private JLabel serverPortLabel = null;
	private JTextField serverPortField = null;
	
	private JLabel multicastIPLabel = null;
	private JTextField multicastIPField = null;
	private JLabel multicastPortLabel = null;
	private JTextField multicastPortField = null;
	
	private JLabel dbDriverLabel = null;
	private JTextField dbDriverField = null;
	private JLabel dbUrlLabel = null;
	private JTextField dbUrlField = null;
	private JLabel dbUserLabel = null;
	private JTextField dbUserField = null;
	private JLabel dbPasswordLabel = null;
	private JPasswordField dbPasswordField = null;
	private JLabel dbConnectionsLabel = null;
	private JTextField dbConnectionsField = null;
	
	private JLabel nicLabel;
	private JLabel addressLabel;
	private JLabel loopbackLabel = new JLabel("");
	private JComboBox nicComboBox = null;
	private JComboBox addressComboBox = null;
	
	private JLabel lanLabel = null;
	private JCheckBox lanCheckBox = null;
	
	private GridBagConstraints serverNameLabelConstraint = null;
	private GridBagConstraints serverNameFieldConstraint = null;
	private GridBagConstraints serverPortLabelConstraint = null;
	private GridBagConstraints serverPortFieldConstraint = null;
	private GridBagConstraints multicastIPLabelConstraint = null;
	private GridBagConstraints multicastIPFieldConstraint = null;
	private GridBagConstraints multicastPortLabelConstraint = null;
	private GridBagConstraints multicastPortFieldConstraint = null;
	private GridBagConstraints dbDriverLabelConstraint = null;
	private GridBagConstraints dbDriverFieldConstraint = null;
	private GridBagConstraints dbUrlLabelConstraint = null;
	private GridBagConstraints dbUrlFieldConstraint = null;
	private GridBagConstraints dbUserLabelConstraint = null;
	private GridBagConstraints dbUserFieldConstraint = null;
	private GridBagConstraints dbPasswordLabelConstraint = null;
	private GridBagConstraints dbPasswordFieldConstraint = null;
	private GridBagConstraints dbConnectionsLabelConstraint = null;
	private GridBagConstraints dbConnectionsFieldConstraint = null;
	private GridBagConstraints nicLabelConstraint = null;
	private GridBagConstraints addressLabelConstraint = null;
	private GridBagConstraints nicComboConstraint = null;
	private GridBagConstraints addressComboConstraint = null;
	private GridBagConstraints loopbackLabelConstraint = null;
	private GridBagConstraints lanLabelConstraint = null;
	private GridBagConstraints lanCheckBoxConstraint = null;
	
	
	private boolean isLoopbackAdapter = false;
	private String nicToConnect = "";
	
	private static final String loopbackMessage = "Loopback adapter selected !\nRLM cannot start properly with this kind of adapter. Please, try another one!";
	
	
	/**
	 * Konstruktor.
	 * @param parent - prozor aplikacije
	 * @author Uros Krkic
	 */
	public SettingsDialog(GUIWindow parent) {
		super(parent, "Settings", true);
		
		this.owner = parent;
		
		initializeLayoutManagers();
		
		createConstraints();
		
		initializeConstraints();
		
		initialize();
	}
	
	
	
	/**
	 * Metod vrsi inicijalizaciju dialoga.
	 * @author Uros Krkic & Martin Jondzic
	 */
	private void initialize() {
		this.setSize(370, 580);
		this.setLocation(owner.getX() + owner.getWidth() / 2 - this.getWidth() / 2, owner.getY() + owner.getHeight() / 2 - this.getHeight() / 2);
		this.setResizable(true);
		this.setContentPane(getJContentPane());
		
		this.setIconImage(owner.getIconImage());
	}
	
	
	private void initializeLayoutManagers() {
		serverGridBag = new GridBagLayout();
		dbGridBag = new GridBagLayout();
		buttonFlow = new FlowLayout(FlowLayout.CENTER);
		
		buttonFlow.setHgap(30);
		
		nicPanelGridBag = new GridBagLayout();
	}
	
	
	private void createConstraints() {
		serverNameLabelConstraint = new GridBagConstraints();
		serverNameFieldConstraint = new GridBagConstraints();
		serverPortLabelConstraint = new GridBagConstraints();
		serverPortFieldConstraint = new GridBagConstraints();
		multicastIPLabelConstraint = new GridBagConstraints();
		multicastIPFieldConstraint = new GridBagConstraints();
		multicastPortLabelConstraint = new GridBagConstraints();
		multicastPortFieldConstraint = new GridBagConstraints();
		dbDriverLabelConstraint = new GridBagConstraints();
		dbDriverFieldConstraint = new GridBagConstraints();
		dbUrlLabelConstraint = new GridBagConstraints();
		dbUrlFieldConstraint = new GridBagConstraints();
		dbUserLabelConstraint = new GridBagConstraints();
		dbUserFieldConstraint = new GridBagConstraints();
		dbPasswordLabelConstraint = new GridBagConstraints();
		dbPasswordFieldConstraint = new GridBagConstraints();
		dbConnectionsLabelConstraint = new GridBagConstraints();
		dbConnectionsFieldConstraint = new GridBagConstraints();
		
		nicLabelConstraint = new GridBagConstraints();
		addressLabelConstraint = new GridBagConstraints();
		nicComboConstraint = new GridBagConstraints();
		addressComboConstraint = new GridBagConstraints();
		loopbackLabelConstraint = new GridBagConstraints();
		
		lanLabelConstraint = new GridBagConstraints();
		lanCheckBoxConstraint = new GridBagConstraints();
	}
	
	
	private void initializeConstraints() {
		serverNameLabelConstraint.gridx = 0;
		serverNameLabelConstraint.gridy = 0;
		serverNameLabelConstraint.weightx = 1;
		serverNameLabelConstraint.weighty = 1;
		serverNameLabelConstraint.anchor = GridBagConstraints.NORTHWEST;
		serverNameLabelConstraint.insets = new Insets(10,5,5,0);
		
		serverNameFieldConstraint.gridx = 1;
		serverNameFieldConstraint.gridy = 0;
		serverNameFieldConstraint.weightx = 1;
		serverNameFieldConstraint.weighty = 1;
		serverNameFieldConstraint.anchor = GridBagConstraints.NORTHWEST;
		serverNameFieldConstraint.insets = new Insets(10,5,5,0);
		
		serverPortLabelConstraint.gridx = 0;
		serverPortLabelConstraint.gridy = 1;
		serverPortLabelConstraint.weightx = 1;
		serverPortLabelConstraint.weighty = 1;
		serverPortLabelConstraint.anchor = GridBagConstraints.NORTHWEST;
		serverPortLabelConstraint.insets = new Insets(0,5,5,0);
		
		serverPortFieldConstraint.gridx = 1;
		serverPortFieldConstraint.gridy = 1;
		serverPortFieldConstraint.weightx = 1;
		serverPortFieldConstraint.weighty = 1;
		serverPortFieldConstraint.anchor = GridBagConstraints.NORTHWEST;
		serverPortFieldConstraint.insets = new Insets(0,5,5,0);

		
		multicastIPLabelConstraint.gridx = 0;
		multicastIPLabelConstraint.gridy = 2;
		multicastIPLabelConstraint.weightx = 1;
		multicastIPLabelConstraint.weighty = 1;
		multicastIPLabelConstraint.anchor = GridBagConstraints.NORTHWEST;
		multicastIPLabelConstraint.insets = new Insets(10,5,5,0);
		
		multicastIPFieldConstraint.gridx = 1;
		multicastIPFieldConstraint.gridy = 2;
		multicastIPFieldConstraint.weightx = 1;
		multicastIPFieldConstraint.weighty = 1;
		multicastIPFieldConstraint.anchor = GridBagConstraints.NORTHWEST;
		multicastIPFieldConstraint.insets = new Insets(10,5,5,0);
		
		multicastPortLabelConstraint.gridx = 0;
		multicastPortLabelConstraint.gridy = 3;
		multicastPortLabelConstraint.weightx = 1;
		multicastPortLabelConstraint.weighty = 1;
		multicastPortLabelConstraint.anchor = GridBagConstraints.NORTHWEST;
		multicastPortLabelConstraint.insets = new Insets(0,5,5,0);
		
		multicastPortFieldConstraint.gridx = 1;
		multicastPortFieldConstraint.gridy = 3;
		multicastPortFieldConstraint.weightx = 1;
		multicastPortFieldConstraint.weighty = 1;
		multicastPortFieldConstraint.anchor = GridBagConstraints.NORTHWEST;
		multicastPortFieldConstraint.insets = new Insets(0,5,5,0);
		
		lanLabelConstraint.gridx = 0;
		lanLabelConstraint.gridy = 4;
		lanLabelConstraint.weightx = 1;
		lanLabelConstraint.weighty = 1;
		lanLabelConstraint.anchor = GridBagConstraints.NORTHWEST;
		lanLabelConstraint.insets = new Insets(0,5,5,0);
		
		lanCheckBoxConstraint.gridx = 1;
		lanCheckBoxConstraint.gridy = 4;
		lanCheckBoxConstraint.weightx = 1;
		lanCheckBoxConstraint.weighty = 1;
		lanCheckBoxConstraint.anchor = GridBagConstraints.NORTHWEST;
		lanCheckBoxConstraint.insets = new Insets(0,5,5,0);

		
		dbDriverLabelConstraint.gridx = 0;
		dbDriverLabelConstraint.gridy = 0;
		dbDriverLabelConstraint.weightx = 1;
		dbDriverLabelConstraint.weighty = 1;
		dbDriverLabelConstraint.anchor = GridBagConstraints.NORTHWEST;
		dbDriverLabelConstraint.insets = new Insets(10,5,5,0);
		
		dbDriverFieldConstraint.gridx = 1;
		dbDriverFieldConstraint.gridy = 0;
		dbDriverFieldConstraint.weightx = 1;
		dbDriverFieldConstraint.weighty = 1;
		dbDriverFieldConstraint.anchor = GridBagConstraints.NORTHWEST;
		dbDriverFieldConstraint.insets = new Insets(10,5,0,0);

		
		dbUrlLabelConstraint.gridx = 0;
		dbUrlLabelConstraint.gridy = 2;
		dbUrlLabelConstraint.weightx = 1;
		dbUrlLabelConstraint.weighty = 1;
		dbUrlLabelConstraint.anchor = GridBagConstraints.NORTHWEST;
		dbUrlLabelConstraint.insets = new Insets(10,5,5,0);
		
		dbUrlFieldConstraint.gridx = 1;
		dbUrlFieldConstraint.gridy = 2;
		dbUrlFieldConstraint.weightx = 1;
		dbUrlFieldConstraint.weighty = 1;
		dbUrlFieldConstraint.anchor = GridBagConstraints.NORTHWEST;
		dbUrlFieldConstraint.insets = new Insets(10,5,0,0);
		
		dbConnectionsLabelConstraint.gridx = 0;
		dbConnectionsLabelConstraint.gridy = 3;
		dbConnectionsLabelConstraint.weightx = 1;
		dbConnectionsLabelConstraint.weighty = 1;
		dbConnectionsLabelConstraint.anchor = GridBagConstraints.NORTHWEST;
		dbConnectionsLabelConstraint.insets = new Insets(10,5,5,0);
		
		dbConnectionsFieldConstraint.gridx = 1;
		dbConnectionsFieldConstraint.gridy = 3;
		dbConnectionsFieldConstraint.weightx = 1;
		dbConnectionsFieldConstraint.weighty = 1;
		dbConnectionsFieldConstraint.anchor = GridBagConstraints.NORTHWEST;
		dbConnectionsFieldConstraint.insets = new Insets(10,5,0,0);
		
		dbUserLabelConstraint.gridx = 0;
		dbUserLabelConstraint.gridy = 4;
		dbUserLabelConstraint.weightx = 1;
		dbUserLabelConstraint.weighty = 1;
		dbUserLabelConstraint.anchor = GridBagConstraints.NORTHWEST;
		dbUserLabelConstraint.insets = new Insets(10,5,5,0);
		
		dbUserFieldConstraint.gridx = 1;
		dbUserFieldConstraint.gridy = 4;
		dbUserFieldConstraint.weightx = 1;
		dbUserFieldConstraint.weighty = 1;
		dbUserFieldConstraint.anchor = GridBagConstraints.NORTHWEST;
		dbUserFieldConstraint.insets = new Insets(10,5,0,0);
		
		dbPasswordLabelConstraint.gridx = 0;
		dbPasswordLabelConstraint.gridy = 5;
		dbPasswordLabelConstraint.weightx = 1;
		dbPasswordLabelConstraint.weighty = 1;
		dbPasswordLabelConstraint.anchor = GridBagConstraints.NORTHWEST;
		dbPasswordLabelConstraint.insets = new Insets(10,5,5,0);
		
		dbPasswordFieldConstraint.gridx = 1;
		dbPasswordFieldConstraint.gridy = 5;
		dbPasswordFieldConstraint.weightx = 1;
		dbPasswordFieldConstraint.weighty = 1;
		dbPasswordFieldConstraint.anchor = GridBagConstraints.NORTHWEST;
		dbPasswordFieldConstraint.insets = new Insets(10,5,0,0);
		

		nicLabelConstraint.gridx = 0;
		nicLabelConstraint.gridy = 0;
		nicLabelConstraint.weightx = 1;
		nicLabelConstraint.weighty = 1;
		nicLabelConstraint.anchor = GridBagConstraints.NORTHWEST;
		nicLabelConstraint.insets = new Insets(5,5,0,0);
		
		nicComboConstraint.gridx = 0;
		nicComboConstraint.gridy = 0;
		nicComboConstraint.weightx = 1;
		nicComboConstraint.weighty = 1;
		nicComboConstraint.anchor = GridBagConstraints.NORTHWEST;
		nicComboConstraint.insets = new Insets(25,5,5,0);
		
		addressLabelConstraint.gridx = 0;
		addressLabelConstraint.gridy = 1;
		addressLabelConstraint.weightx = 1;
		addressLabelConstraint.weighty = 1;
		addressLabelConstraint.anchor = GridBagConstraints.NORTHWEST;
		addressLabelConstraint.insets = new Insets(10,5,0,0);
		
		addressComboConstraint.gridx = 0;
		addressComboConstraint.gridy = 1;
		addressComboConstraint.weightx = 1;
		addressComboConstraint.weighty = 1;
		addressComboConstraint.anchor = GridBagConstraints.NORTHWEST;
		addressComboConstraint.insets = new Insets(5,100,5,0);
		
		loopbackLabelConstraint.gridx = 0;
		loopbackLabelConstraint.gridy = 1;
		loopbackLabelConstraint.weightx = 1;
		loopbackLabelConstraint.weighty = 1;
		loopbackLabelConstraint.anchor = GridBagConstraints.NORTHWEST;
		loopbackLabelConstraint.insets = new Insets(10,250,0,0);

	}

	
	
	
	// Metode koje inicijalizuju komponente dialoga.
	
	private JPanel getJContentPane() {
		if (jContentPane == null) {
			jContentPane = new JPanel();
			
//			jContentPane.setLayout(new BorderLayout());

			GridBagLayout gb = new GridBagLayout();
			
			jContentPane.setLayout(gb);
			GridBagConstraints c0 = new GridBagConstraints();
			GridBagConstraints c1 = new GridBagConstraints();
			GridBagConstraints c2 = new GridBagConstraints();
			GridBagConstraints c3 = new GridBagConstraints();
			c0.gridx = 0;
			c0.gridy = 0;
			c0.weightx = 1;
			c0.weighty = 1;
			c0.fill = GridBagConstraints.HORIZONTAL;
			c0.anchor = GridBagConstraints.NORTHWEST;
			c0.insets = new Insets(5,5,5,5);
			
			c1.gridx = 0;
			c1.gridy = 1;
			c1.weightx = 1;
			c1.weighty = 1;
			c1.fill = GridBagConstraints.HORIZONTAL;
			c1.anchor = GridBagConstraints.NORTHWEST;
			c1.insets = new Insets(5,5,5,5);
			
			c2.gridx = 0;
			c2.gridy = 2;
			c2.weightx = 1;
			c2.weighty = 1;
			c2.fill = GridBagConstraints.HORIZONTAL;
			c2.anchor = GridBagConstraints.NORTHWEST;
			c2.insets = new Insets(5,5,5,5);
			
			c3.gridx = 0;
			c3.gridy = 3;
			c3.weightx = 1;
			c3.weighty = 1;
			c3.fill = GridBagConstraints.HORIZONTAL;
			c3.anchor = GridBagConstraints.NORTHWEST;
			c3.insets = new Insets(5,5,5,5);
			
			gb.setConstraints(getServerPanel(), c0);
			gb.setConstraints(getFolderPanel(), c1);
			gb.setConstraints(getNicPanel(), c2);
			gb.setConstraints(getButtonPanel(), c3);
			
			jContentPane.add(getServerPanel());
			jContentPane.add(getFolderPanel());
			jContentPane.add(getNicPanel());
			jContentPane.add(getButtonPanel());
		}
		
		return jContentPane;
	}

	
	
	private JPanel getServerPanel() {
		if (serverPanel == null) {
			serverPanel = new JPanel();
			
			serverPanel.setLayout(serverGridBag);
			
			TitledBorder titledBorder = BorderFactory.createTitledBorder(BorderFactory.
					createEtchedBorder(EtchedBorder.RAISED),
					"Server Setttings", javax.swing.border.TitledBorder.CENTER,
					javax.swing.border.TitledBorder.DEFAULT_POSITION,
					null, null);
			
			serverPanel.setBorder(titledBorder);
			
			serverPanel.add(getServerNameLabel());
			serverPanel.add(getServerNameField());
			serverPanel.add(getServerPortLabel());
			serverPanel.add(getServerPortField());
			serverPanel.add(getMulticastIPLabel());
			serverPanel.add(getMulticastIPField());
			serverPanel.add(getMulticastPortLabel());
			serverPanel.add(getMulticastPortField());
			serverPanel.add(getLanLabel());
			serverPanel.add(getLanCheckBox());
		}
		
		return serverPanel;
	}
	
	
	private JPanel getFolderPanel() {
		if (databasePanel == null) {
			databasePanel = new JPanel();
			
			databasePanel.setLayout(dbGridBag);
			
			TitledBorder titledBorder = BorderFactory.createTitledBorder(BorderFactory.
					createEtchedBorder(EtchedBorder.RAISED),
					"Database Settings", javax.swing.border.TitledBorder.CENTER,
					javax.swing.border.TitledBorder.DEFAULT_POSITION,
					null, null);
			
			databasePanel.setBorder(titledBorder);
			
			databasePanel.add(getDbDriverLabel());
			databasePanel.add(getDbDriverField());
			databasePanel.add(getDbUrlLabel());
			databasePanel.add(getDbUrlField());
			databasePanel.add(getDbUserLabel());
			databasePanel.add(getDbUserField());
			databasePanel.add(getDbPasswordLabel());
			databasePanel.add(getDbPasswordField());
			databasePanel.add(getDbConnectionsLabel());
			databasePanel.add(getDbConnectionsField());
		}
		
		return databasePanel;
	}
	
	
	private JPanel getButtonPanel() {
		if (buttonPanel == null) {
			buttonPanel = new JPanel();
			buttonPanel.setLocation(5, 90);
			buttonPanel.setSize(300,70);
			buttonPanel.setLayout(buttonFlow);
			
			Border border = BorderFactory.createEtchedBorder(EtchedBorder.RAISED);
			buttonPanel.setBorder(border);
			
			buttonPanel.add(getOKButton());
			buttonPanel.add(getCancelButton());
		}
		
		return buttonPanel;
	}
	
	private JButton getOKButton() {
		if (okButton == null) {
			okButton = new JButton("OK");
			okButton.setToolTipText("OK");
			okButton.setPreferredSize(new Dimension(80, 25));
			
			okButton.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					
					SettingsDialog.this.setCursor(new Cursor(Cursor.WAIT_CURSOR));
					
					if ( !changeMade() ) {
						SettingsDialog.this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
						SettingsDialog.this.dispose();
	
						return;
					}
					
					if ( changePortMade() ) {
						boolean portValidationValue = PortScanner.validationWithInfo(serverPortField, "Server Port");
						if (portValidationValue == false) {
							SettingsDialog.this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
							return;
						}
						
//						try {
//							Integer.parseInt(serverPortField.getText());
//						}
//						catch (Exception ex) {
//							MessageViewer.showError(SettingsDialog.this, "Port Number must be a number!");
//							return;
//						}

						
						UPnpManager.removeTcpForward(RlmServerParameters.getServerPort());
						RlmServerParameters.setServerPort(Integer.parseInt(serverPortField.getText()));
						UPnpManager.addTcpForward("RLM_Server", RlmServerParameters.getServerPort(), RlmServerParameters.getServerPort(), RlmServerParameters.getNetworkInterfaceToConnect());
					}
			
			
					if ( isLoopbackAdapter ) {
						JOptionPane.showMessageDialog(SettingsDialog.this, loopbackMessage, "Loopback Adapter Warning", JOptionPane.WARNING_MESSAGE);
						SettingsDialog.this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
						return;
					}

					if ( changeNicToConnectMade() ) {
						UPnpManager.removeTcpForward(RlmServerParameters.getServerPort());
						
						String nicToConnectTemp = nicToConnect;
						
						if ( nicToConnectTemp.equals("auto_select") ) {
							nicToConnectTemp = NetworkUtils.getLocalAddress().getHostAddress();
							
							// zbog discavery timeout-a
							try {
								Thread.sleep(4000);
							} catch (InterruptedException ex) {
								ex.printStackTrace();
							}
						}
						
						RlmServerParameters.setNetworkInterfaceToConnect(nicToConnect);
						UPnpManager.addTcpForward("RLM_Server", RlmServerParameters.getServerPort(), RlmServerParameters.getServerPort(), nicToConnectTemp);
					}
					
					
					RlmServerParameters.setLan(lanCheckBox.isSelected());
					
					RlmServerParameters.setServerIP(serverNameField.getText());
					RlmServerParameters.setServerPort(Integer.parseInt(serverPortField.getText()));
					RlmServerParameters.setMulticastIP(multicastIPField.getText());
					RlmServerParameters.setMulticastPort(Integer.parseInt(multicastPortField.getText()));
					RlmServerParameters.setDbDriver(dbDriverField.getText());
					RlmServerParameters.setDbUrl(dbUrlField.getText());
					RlmServerParameters.setDbUser(dbUserField.getText());
					RlmServerParameters.setDbPassword(new String(dbPasswordField.getPassword()));
					RlmServerParameters.setMaxDBConnections(Integer.parseInt(dbConnectionsField.getText()));
					
					RlmServerParameters.setNetworkInterfaceToConnect(nicToConnect);
					
					if ( NICManager.getNICByAddress(nicToConnect) == null ) {
						RlmServerParameters.setMACAddress(DefaultParameterValues.MAC_ADDRESS);
					}
					else {
						RlmServerParameters.setMACAddress(NICManager.getNICByAddress(nicToConnect).getNicMACAddress());
					}
					
					
					RlmServerParameters.storeParameters();
					
					SettingsDialog.this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
					
					SettingsDialog.this.dispose();
					
				}
			});
		}
		
		return okButton;
	}
	
	
	private boolean changeMade() {
		if (
			serverNameField.getText().equals(RlmServerParameters.getServerIP()) &&
			serverPortField.getText().equals(Integer.toString(RlmServerParameters.getServerPort())) &&
			multicastIPField.getText().equals(RlmServerParameters.getMulticastIP()) &&
			multicastPortField.getText().equals(Integer.toString(RlmServerParameters.getMulticastPort())) &&
			dbDriverField.getText().equals(RlmServerParameters.getDbDriver()) &&
			dbUrlField.getText().equals(RlmServerParameters.getDbUrl()) &&
			dbUserField.getText().equals(RlmServerParameters.getDbUser()) &&
			(new String(dbPasswordField.getPassword())).equals(RlmServerParameters.getDbPassword()) &&
			dbConnectionsField.getText().equals(Integer.toString(RlmServerParameters.getMaxDBConnections())) &&
			nicToConnect.equals(RlmServerParameters.getNetworkInterfaceToConnect(true)) &&
			lanCheckBox.isSelected() == RlmServerParameters.isLan()
		) {
			return false;
		}
		else {
			return true;
		}
	}
	

	private boolean changePortMade() {
		return ( !serverPortField.getText().equals(Integer.toString(RlmServerParameters.getServerPort())) );
	}
	
	private boolean changeNicToConnectMade() {
		return ( !nicToConnect.equals(RlmServerParameters.getNetworkInterfaceToConnect(true)) );
	}
	
	private JButton getCancelButton() {
		if (cancelButton == null) {
			cancelButton = new JButton("Cancel");
			cancelButton.setToolTipText("Cancel");
			cancelButton.setPreferredSize(new Dimension(80, 25));
			cancelButton.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					SettingsDialog.this.dispose();
				}
			});
		}
		
		return cancelButton;
	}



	private JTextField getDbDriverField() {
		if (dbDriverField == null) {
			dbDriverField = new JTextField();
			dbDriverField.setPreferredSize(new Dimension(200,20));
			dbGridBag.setConstraints(dbDriverField, dbDriverFieldConstraint);
			dbDriverField.setText(RlmServerParameters.getDbDriver());
		}
		return dbDriverField;
	}



	private JLabel getDbDriverLabel() {
		if (dbDriverLabel == null) {
			dbDriverLabel = new JLabel("Database Driver:");
			dbGridBag.setConstraints(dbDriverLabel, dbDriverLabelConstraint);
		}
		return dbDriverLabel;
	}
	
	private JTextField getDbUrlField() {
		if (dbUrlField == null) {
			dbUrlField = new JTextField();
			dbUrlField.setPreferredSize(new Dimension(200,20));
			dbGridBag.setConstraints(dbUrlField, dbUrlFieldConstraint);
			dbUrlField.setText(RlmServerParameters.getDbUrl());
		}
		return dbUrlField;
	}



	private JLabel getDbUrlLabel() {
		if (dbUrlLabel == null) {
			dbUrlLabel = new JLabel("Database URL:");
			dbGridBag.setConstraints(dbUrlLabel, dbUrlLabelConstraint);
		}
		return dbUrlLabel;
	}
	
	private JTextField getDbUserField() {
		if (dbUserField == null) {
			dbUserField = new JTextField();
			dbUserField.setPreferredSize(new Dimension(200,20));
			dbGridBag.setConstraints(dbUserField, dbUserFieldConstraint);
			dbUserField.setText(RlmServerParameters.getDbUser());
		}
		return dbUserField;
	}



	private JLabel getDbUserLabel() {
		if (dbUserLabel == null) {
			dbUserLabel = new JLabel("Database user:");
			dbGridBag.setConstraints(dbUserLabel, dbUserLabelConstraint);
		}
		return dbUserLabel;
	}
	
	private JPasswordField getDbPasswordField() {
		if (dbPasswordField == null) {
			dbPasswordField = new JPasswordField();
			dbPasswordField.setPreferredSize(new Dimension(200,20));
			dbGridBag.setConstraints(dbPasswordField, dbPasswordFieldConstraint);
			dbPasswordField.setText(RlmServerParameters.getDbPassword());
		}
		return dbPasswordField;
	}



	private JLabel getDbPasswordLabel() {
		if (dbPasswordLabel == null) {
			dbPasswordLabel = new JLabel("Database password:");
			dbGridBag.setConstraints(dbPasswordLabel, dbPasswordLabelConstraint);
		}
		return dbPasswordLabel;
	}

	private JTextField getDbConnectionsField() {
		if (dbConnectionsField == null) {
			dbConnectionsField = new JTextField();
			dbConnectionsField.setPreferredSize(new Dimension(50,20));
			dbGridBag.setConstraints(dbConnectionsField, dbConnectionsFieldConstraint);
			dbConnectionsField.setText(Integer.toString(RlmServerParameters.getMaxDBConnections()));
		}
		return dbConnectionsField;
	}



	private JLabel getDbConnectionsLabel() {
		if (dbConnectionsLabel == null) {
			dbConnectionsLabel = new JLabel("DB connections:");
			dbGridBag.setConstraints(dbConnectionsLabel, dbConnectionsLabelConstraint);
		}
		return dbConnectionsLabel;
	}
	
	

	private JTextField getServerNameField() {
		if (serverNameField == null) {
			serverNameField = new JTextField();
			serverNameField.setPreferredSize(new Dimension(100,20));
			serverGridBag.setConstraints(serverNameField, serverNameFieldConstraint);
			serverNameField.setText(RlmServerParameters.getServerIP());
		}
		return serverNameField;
	}



	private JLabel getServerNameLabel() {
		if (serverNameLabel == null) {
			serverNameLabel = new JLabel("Server Name or IP:");
			serverGridBag.setConstraints(serverNameLabel, serverNameLabelConstraint);
		}
		return serverNameLabel;
	}



	private JTextField getServerPortField() {
		if (serverPortField == null) {
			serverPortField = new JTextField();
			serverPortField.setPreferredSize(new Dimension(50,20));
			serverGridBag.setConstraints(serverPortField, serverPortFieldConstraint);
			serverPortField.setText(Integer.toString(RlmServerParameters.getServerPort()));
		}
		return serverPortField;
	}



	private JLabel getServerPortLabel() {
		if (serverPortLabel == null) {
			serverPortLabel = new JLabel("Server Port:");
			serverGridBag.setConstraints(serverPortLabel, serverPortLabelConstraint);
		}
		return serverPortLabel;
	}
	
	
	private JTextField getMulticastIPField() {
		if (multicastIPField == null) {
			multicastIPField = new JTextField();
			multicastIPField.setPreferredSize(new Dimension(100,20));
			serverGridBag.setConstraints(multicastIPField, multicastIPFieldConstraint);
			multicastIPField.setText(RlmServerParameters.getMulticastIP());
		}
		return multicastIPField;
	}



	private JLabel getMulticastIPLabel() {
		if (multicastIPLabel == null) {
			multicastIPLabel = new JLabel("Multicast IP:");
			serverGridBag.setConstraints(multicastIPLabel, multicastIPLabelConstraint);
		}
		return multicastIPLabel;
	}


	private JTextField getMulticastPortField() {
		if (multicastPortField == null) {
			multicastPortField = new JTextField();
			multicastPortField.setPreferredSize(new Dimension(50,20));
			serverGridBag.setConstraints(multicastPortField, multicastPortFieldConstraint);
			multicastPortField.setText(Integer.toString(RlmServerParameters.getMulticastPort()));
		}
		return multicastPortField;
	}



	private JLabel getMulticastPortLabel() {
		if (multicastPortLabel == null) {
			multicastPortLabel = new JLabel("Multicast Port:");
			serverGridBag.setConstraints(multicastPortLabel, multicastPortLabelConstraint);
		}
		return multicastPortLabel;
	}
	
	

	private JLabel getNicLabel() {
		if (nicLabel == null) {
			nicLabel = new JLabel("NIC Adapter:");
			nicPanelGridBag.setConstraints(nicLabel, nicLabelConstraint);
		}
		return nicLabel;
	}
	
	private JLabel getAddressLabel() {
		if (addressLabel == null) {
			addressLabel = new JLabel("Address:");
			nicPanelGridBag.setConstraints(addressLabel, addressLabelConstraint);
		}
		return addressLabel;
	}
	
	private JComboBox getNicComboBox() {
		if (nicComboBox == null) {
			nicComboBox = new JComboBox(NICManager.getAdapters());
			nicPanelGridBag.setConstraints(nicComboBox, nicComboConstraint);
			nicComboBox.setPreferredSize(new Dimension(330,25));

			NICInfo nicInfo = NICManager.getNICByAddress(RlmServerParameters.getNetworkInterfaceToConnect(true));
			
			if (nicInfo != null) {
				nicComboBox.setSelectedItem(nicInfo);
			}

			nicComboBox.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					setAddresses();
				}
			});
		}
		return nicComboBox;
	}

	
	private JCheckBox getLanCheckBox() {
		if (lanCheckBox == null) {
			lanCheckBox = new JCheckBox();
			serverGridBag.setConstraints(lanCheckBox, lanCheckBoxConstraint);
			lanCheckBox.setSelected(RlmServerParameters.isLan());
		}
		return lanCheckBox;
	}



	private JLabel getLanLabel() {
		if (lanLabel == null) {
			lanLabel = new JLabel("Is in LAN:");
			serverGridBag.setConstraints(lanLabel, lanLabelConstraint);
		}
		return lanLabel;
	}
	
	
	private JComboBox getAddressComboBox() {
		if (addressComboBox == null) {
			addressComboBox = new JComboBox();
			addressComboBox.setPreferredSize(new Dimension(130,25));
			setAddresses();
			if (RlmServerParameters.getNetworkInterfaceToConnect(true) != null)
				addressComboBox.setSelectedItem(RlmServerParameters.getNetworkInterfaceToConnect(true));
			nicPanelGridBag.setConstraints(addressComboBox, addressComboConstraint);
			
			addressComboBox.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					if (addressComboBox.getSelectedItem() != null)
						nicToConnect = addressComboBox.getSelectedItem().toString();
				}
			});
		}
		return addressComboBox;
	}


	
	private void setAddresses() {
		addressComboBox.removeAllItems();
		NICInfo temp = (NICInfo)nicComboBox.getSelectedItem();
		if (temp == null)
			return;
		
		if ( temp.getNICName().equals("auto_select") ) {
			isLoopbackAdapter = false;
			loopbackLabel.setForeground(Color.BLACK);
			loopbackLabel.setText("");
			nicToConnect = temp.getNICName();
			addressComboBox.addItem(nicToConnect);
//			addressComboBox.addItem("0.0.0.0");
		}
		
		for (InetAddress addr : temp.getNICAddresses()) {
			if (addr.isLoopbackAddress()) {
				loopbackLabel.setForeground(Color.RED);
				loopbackLabel.setText("Loopback !");
				isLoopbackAdapter = true;
			}
			else {
				loopbackLabel.setForeground(Color.BLACK);
				loopbackLabel.setText("");
				isLoopbackAdapter = false;
			}
			addressComboBox.addItem(addr.getHostAddress());
			nicToConnect = addr.getHostAddress();
		}
	}
	
	
	private JPanel getNicPanel() {
		if (nicPanel == null) {
			nicPanel = new JPanel();
			
			nicPanel.setLayout(nicPanelGridBag);
			
			TitledBorder titledBorder = BorderFactory.createTitledBorder(BorderFactory.
					createEtchedBorder(EtchedBorder.RAISED),
					"Network Settings", javax.swing.border.TitledBorder.CENTER,
					javax.swing.border.TitledBorder.DEFAULT_POSITION,
					null, null);
			
			nicPanel.setBorder(titledBorder);
			
			nicPanel.add(getNicLabel());
			nicPanel.add(getNicComboBox());
			nicPanel.add(getAddressLabel());
			nicPanel.add(getAddressComboBox());
			nicPanel.add(getLoopbackLabel());
		}
		
		return nicPanel;
	}
	
	
	private JLabel getLoopbackLabel() {
		nicPanelGridBag.setConstraints(loopbackLabel, loopbackLabelConstraint);
		return loopbackLabel;
	}


}
